package com.tyoue.core;

import com.tyoue.login.Login;
import com.tyoue.login.WebParameter;
import org.openqa.selenium.*;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.FileWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 核心代码,实现IE浏览器爬虫
 *
 * @author Tyoui
 * @version 18.4.23
 */
public class IE {
    //web驱动
    private WebDriver webDriver;
    //获取最里面的窗口话柄
    private String nowHandle;
    //已经爬到多少页
    private int startPage;

    /**
     * 初始化操作。打开浏览器去除保护模式，实现最大化窗口
     * 获取网页链接
     */
    private void init() {
        System.setProperty(Login.DRIVER_IE_NAME, Login.DRIVER_IE_PATH);
        InternetExplorerOptions internetExplorerOptions = new InternetExplorerOptions();
        internetExplorerOptions.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
        webDriver = new InternetExplorerDriver(null, internetExplorerOptions);
        maximize();
        webDriver.get(Login.URL);
    }

    /**
     * 打开网页登陆界面
     * 实现自动登陆
     * 账号自动填充，密码需要记住
     */
    private void webIE() {
        webDriver.findElement(By.id(WebParameter.WEB_IE_TXTUSERNAME)).sendKeys(Login.USER);
        webDriver.findElement(By.id(WebParameter.WEB_IE_Login)).click();
    }

    /**
     * 打开管理界面
     * 切换话柄，点击管理界面进入详细数据界面
     */
    private void manage() {
        loopHandle();
        webDriver.findElement(By.id(WebParameter.MANAGE_CLICK)).click();
        delay(5);
    }

    /**
     * 实现延迟操作
     *
     * @param time 等待时间
     */
    private void delay(int time) {
        webDriver.manage().timeouts().implicitlyWait(time, TimeUnit.SECONDS);
    }

    /**
     * 循环获取话柄。获得最新的窗口话柄
     */
    private void loopHandle() {
        Set<String> handles = webDriver.getWindowHandles();
        for (String handle : handles)
            webDriver.switchTo().window(handle);
    }

    /**
     * 实现窗口最大化操作
     */
    private void maximize() {
        webDriver.manage().window().maximize();
    }

    /**
     * 获取第三层frame话柄
     */
    private void findFrame() {
        webDriver.switchTo().frame(WebParameter.DATA_ONE_FRAME);
        webDriver.switchTo().frame(WebParameter.DATA_TWO_FRAME);
        webDriver.switchTo().frame(WebParameter.DATA_THREE_FRAME);
    }

    /**
     * 爬取最三层的数据，获得最里的点击连接
     *
     * @return 当前页的所有点击连接
     */
    private List<String> dataList() {
        String source = webDriver.getPageSource();
        Pattern pattern = Pattern.compile(WebParameter.REG);
        Matcher matcher = pattern.matcher(source);
        List<String> list = new ArrayList<>();
        while (matcher.find()) {
            String address = matcher.group();
            address = address.substring(2, address.length() - 1);
            list.add(address);
        }
        return list;
    }

    /**
     * 获取当前数据详细界面的话柄
     */
    private void dataManage() {
        maximize();
        nowHandle = webDriver.getWindowHandle();
    }

    /**
     * 循环爬取数据
     * 并且保存在D盘下的世纪城社区中
     * 文件名字是档案号
     *
     * @throws Exception 爬取失败或者保存失败
     */
    private void getDetailData() throws Exception {
        JavascriptExecutor javascriptExecutor = (JavascriptExecutor) webDriver;
        List<String> list = dataList();
        for (String str : list) {
            javascriptExecutor.executeScript("LookDetail(" + str + ",\"\",\"0\")");
            loopHandle();
            Writer writer = new FileWriter(Login.DIC + str + ".txt");
            writer.write(webDriver.getPageSource());
            writer.close();
            System.out.println("爬取成功!档案号为:" + str);
            webDriver.switchTo().window(nowHandle);
            findFrame();
        }
        webDriver.switchTo().window(nowHandle);
    }

    /**
     * 切换下一页界面
     *
     * @param page 下一页页码
     */
    private void next(String page) {
        findFrame();
        WebElement webElement = webDriver.findElement(By.id(WebParameter.NEXT));
        webElement.sendKeys(page);
        webElement.click();
        delay(20);
    }

    /**
     * 合并实现爬虫
     *
     * @param startPage 开始页码
     * @param endPage   结束页码
     * @throws Exception 爬取异常
     */
    public void start(int startPage, int endPage) throws Exception {
        init();
        webIE();
        manage();
        loopHandle();
        for (int i = startPage; i <= endPage; i++) {
            next("" + i);
            dataManage();
            getDetailData();
            System.out.println("已经完成！第" + i + "页");
            this.startPage = i + 1;
        }
    }

    /**
     * 关闭所有的界面
     */
    public void close() {
        try {
            webDriver.quit();
        } catch (Exception e) {
            webDriver.close();
        }

    }

    /**
     * 获取当前是多少页
     *
     * @return 当前页码
     */
    public int getStartPage() {
        return startPage;
    }

    /**
     * 第一次初始化页码
     *
     * @param startPage 起始页
     */
    public void setStartPage(int startPage) {
        this.startPage = startPage;
    }
}